/*
指示符
宏的参数使用一个美元符号 $ 作为前缀，并使用一个指示符（designator）来注明类型

这里列出全部指示符：

block
expr 用于表达式
ident 用于变量名或函数名
item
literal 用于字面常量
pat (模式 pattern)
path
stmt (语句 statement)
tt (标记树 token tree)
ty (类型 type)
vis (可见性描述符)

*/

macro_rules! create_function {
    // 此宏接受一个 `ident` 指示符表示的参数，并创建一个名为 `$func_name` 的函数
    // `ident` 指示符用于变量名或函数名
    ($func_name: ident) => (
        fn $func_name() {
            // `stringify!` 宏把 `ident` 转换成字符串
            println!("You called {:?}()", stringify!($func_name))
        }
    )
}

// 借助上述宏来创建名为 `foo` 和 `bar` 的函数
create_function!(foo);
create_function!(bar);

macro_rules! print_result {
    // 此宏接受一个 `expr` 类型的表达式，并将它作为字符串，连同其结果一起打印出来
    // `expr` 指示符表示表达式
    ($expression:expr) => (
        // `stringify!` 把表达式*原样*转换成一个字符串
        println!("{:?} = {:?}", stringify!($expression), $expression)
    )
}

fn main() {
    foo();
    bar();

    print_result!(1u32 + 1);
}